package com.ruoyi.util;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * **********************
 * * Author: XiaShiLong *
 * * Date  : 2021-05-13 *
 * * Time  : 15:59      *
 * * to    : lz&xm      *
 * **********************
 **/
public class ReflectUtil {

    public static <T> Class<T> getClass(String classPath) {
        try {
            return (Class<T>) Class.forName(classPath);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("类路径异常!");
        }
    }

    public static Field[] getFieldHaveSuperclass(Class<?> clz) {
        List<Field> list = new ArrayList<>();
        while (clz != null) {
            list.addAll(Arrays.asList(clz.getDeclaredFields()));
            clz = clz.getSuperclass();
        }
        return list.toArray(new Field[0]);
    }

    public static Field[] getField(Class<?> clz) {
        return clz.getDeclaredFields();
    }

    public static <T> String getFieldName(SerializableFunction<T, ?> func) {
        try {
            Method method = func.getClass().getDeclaredMethod("writeReplace");
            method.setAccessible(Boolean.TRUE);
            return resolveFieldName(((SerializedLambda) method.invoke(func)).getImplMethodName());
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException(e);
        }
    }

    private static String resolveFieldName(String getMethodName) {
        if (getMethodName.startsWith("get")) {
            getMethodName = getMethodName.substring(3);
        } else if (getMethodName.startsWith("is")) {
            getMethodName = getMethodName.substring(2);
        }
        return firstToLowerCase(getMethodName);
    }

    private static String firstToLowerCase(String param) {
        if (StringUtils.isBlank(param)) {
            return "";
        }
        return param.substring(0, 1).toLowerCase() + param.substring(1);
    }
}
